/*
* Copyright (C) 2004-2010  Autodesk, Inc.
* 
* This library is free software; you can redistribute it and/or
* modify it under the terms of version 2.1 of the GNU Lesser
* General Public License as published by the Free Software Foundation.
* 
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
*/

#include <stdafx.h>
#include <OWS/FdoOwsGetCapabilities.h>
#include <OWS/FdoOwsResponse.h>
#include "FdoCMSGoogleDelegate.h"
#include "FdoCMSGoogleGetMap.h"
#include "FdoCMSXmlGlobals.h"
#include "FdoCMSRasterGdal.h"
#include <gdal.h>
#include <gdal_priv.h>

FdoCMSGoogleDelegate::FdoCMSGoogleDelegate()
{
    FdoCMSGoogleDelegate(NULL,NULL);
}

FdoCMSGoogleDelegate::FdoCMSGoogleDelegate(FdoString* serviceUrl,FdoString* apiKey) :
FdoCMSDelegate(serviceUrl, apiKey)
{
    _InitZoomLevel();
}

FdoCMSGoogleDelegate::~FdoCMSGoogleDelegate()
{
}

void FdoCMSGoogleDelegate::Dispose()
{ 
    delete this; 
}

FdoBoolean FdoCMSGoogleDelegate::TestConnection()
{
    return true;
}

GDALDataset*
FdoCMSGoogleDelegate::GetMapGdalDataset(FdoCMSBoundingBox* bbox,
                                      FdoSize height,
                                      FdoSize width,
                                      FdoString* mapType,
                                      FdoDouble& retScale)
{
    VALIDATE_ARGUMENT (bbox);
    VALIDATE_ARGUMENT (mapType);

    FdoDouble minX = bbox->GetMinX ();
    FdoDouble maxX = bbox->GetMaxX ();

    FdoSize heightOut = height;
    FdoSize widthOut = width;
    FdoInt32 zoomLevel = 0;

    // We should handle this scenario - the expected image size is lager than the biggest image size with one query.
    // and this scenario - the expected image size is smaller than the smallest image size with one query.
    // TODO: the smaller size.
    if(SplitImageNeeded(bbox, height, width, FdoCMSXmlGlobals::CMSGoogleMaxZoomLevel, heightOut, widthOut, zoomLevel))
    {
        FdoCMSImageSpaceTileManager* pTileMan = SplitImage(bbox, zoomLevel, heightOut, widthOut);
        pTileMan->BeginRead();
        int rasterBandNum = 0;
        for(FdoSize iY = 0; iY < pTileMan->CountY(); iY++)
        {
            for(FdoSize iX = 0; iX < pTileMan->CountX(); iX++)
            {
                FdoCMSImageSpaceTile* pTile = pTileMan->ReadNext();
                if(NULL != pTile)
                {
                    FdoCMSBoundingBox* bboxNow = pTile->m_boundingBox;
                    FdoDouble centerX = bboxNow->GetCenterX();
                    FdoDouble centerY = bboxNow->GetCenterY();
                    int iLogoHeight = 2 * FdoCMSBoundingBox::GetLogoHeight(iX, iY, pTileMan->CountX(), pTileMan->CountY());
                    DelegateParams* params = new DelegateParams;
                    params->dCenterLat = centerY;
                    params->dCenterLon = centerX;
                    params->iZoomLevel = zoomLevel;
                    params->width = pTile->m_width;
                    params->height = pTile->m_height + iLogoHeight;
                    params->imageFormat = L"jpeg";
                    params->mapType = mapType;
                    params->apiKey = m_apiKey;
                    pTile->SetDelegateParams(params);

                    //FdoPtr<FdoCMSGoogleGetMap> request = FdoCMSGoogleGetMap::Create(centerY,centerX,zoomLevel,pTile->m_height + iLogoHeight,pTile->m_width,L"jpeg",mapType,this->m_apiKey);
                    //FdoPtr<FdoOwsResponse> response = Invoke (request);
                    //int rasterBandNumTemp = pTile->SetIoStream(response->GetStream());
                    //if(rasterBandNum == 0)
                    //    rasterBandNum = rasterBandNumTemp;
                    //assert(rasterBandNumTemp == rasterBandNum);
                }
                else
                {
                    assert(0);
                }
            }
        }
        pTileMan->EndRead();
        FdoSize tileCount = pTileMan->CountX() * pTileMan->CountY();
        rasterBandNum = pTileMan->DoQueryGoogle(tileCount);
        return pTileMan->MergeImageTilesGDAL(rasterBandNum);
    }
    assert(0);
    return NULL;
}
